package com.alatus.aspect;

import com.alatus.commons.DataScope;
import com.alatus.constant.Constants;
import com.alatus.model.TUser;
import com.alatus.query.BaseQuery;
import com.alatus.util.JWTUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.List;

@Component
@Aspect
public class DataScopeAspect {
    @Pointcut(value = "@annotation(com.alatus.commons.DataScope)")
    private void pointCut(){

    }

    @Around(value = "pointCut()")
    public Object process(ProceedingJoinPoint joinPoint) throws Throwable {
//        通过连接点获得签名对象
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
//        转为签名方法对象获得方法(源方法)在原方法上获取指定注解
        DataScope dataScope = methodSignature.getMethod().getDeclaredAnnotation(DataScope.class);
        String tableAlias = dataScope.tableAlias();
        String tableField = dataScope.tableField();
//        在web容器获取当前请求的request对象
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//        从请求头中获取我们的token
        String token = request.getHeader(Constants.TOKEN_NAME);
//        解析token
        TUser tUser = JWTUtils.parseUserFromJWT(token);
//        已经获取了用户的角色
        List<String> roleList = tUser.getRoleList();
//        不包含管理员角色,查自己的数据,拼装SQL
        if (!roleList.contains(Constants.ADMIN)) {
//            获取这个方法的形参的第一个参数
            Object params = joinPoint.getArgs()[0];
            if(params instanceof BaseQuery){
                BaseQuery query = (BaseQuery)params;
                query.setFilterSQL(" and "+tableAlias+"."+tableField+"="+tUser.getId());
            }
        }
//        joinPoint.proceed()前是方法执行前
//        如果还有业务代码可以提取出来,写到后面去
        return joinPoint.proceed();
    }
}
